package com.seven.thread;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author sevenDay
 * @classname SevenThreadPoolExecutor
 * @description: 描述TODO
 * @date 2018/7/19
 */
public class SevenThreadPoolExecutor extends ThreadPoolExecutor {


    /**
     * 默认实现基础的构造函数
     * @param corePoolSize
     * @param maximumPoolSize
     * @param keepAliveTime
     * @param unit
     * @param workQueue
     */
    public SevenThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    public SevenThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    public SevenThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public SevenThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    /**
     * 进行执行任务之前的定义
     * @param t 工作线程
     * @param r 执行任务
     */
    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        try {
            setStartTime(r);
        }finally {
            //设置时间
            super.beforeExecute(t, r);
        }

    }

    /**
     * 任务执行之后的实现
     * @param r
     * @param t
     */
    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        try {
            setEndTime(r);
        }
        finally {
            super.afterExecute(r, t);
        }

    }

    /**
     * 线程池执行完之后
     */
    @Override
    protected void terminated() {
        super.terminated();
    }

    /**
     * 进行执行任务之前的时间设定
     * @param r
     */
    private void setStartTime(Runnable r){
        SevenFutureTask futureTask = (SevenFutureTask) r;
        Runnable runnable = futureTask.getRunnable();
        Long time = System.nanoTime();
        if (runnable instanceof SevenRunnable){
            SevenRunnable s = (SevenRunnable)runnable;
            s.setStartTime(time);
        }else if(runnable instanceof SevenThread){
            SevenThread s = (SevenThread)runnable;
            s.setStartTime(time);
        }else if (runnable instanceof Callable){
            SevenCallable s = (SevenCallable)runnable;
            s.setStartTime(time);
        }
    }
    /**
     *进行执行任务之后的时间设定
     * @param r
     */
    private void setEndTime(Runnable r){
        SevenFutureTask futureTask = (SevenFutureTask) r;
        Runnable thread = futureTask.getRunnable();
        Long time =  System.nanoTime();
        if (thread instanceof SevenRunnable){
            SevenRunnable s = (SevenRunnable)thread;
            s.setEndTime(time);
        }else if(thread instanceof SevenThread){
            SevenThread s = (SevenThread)thread;
            s.setEndTime(time);
        }else if (thread instanceof Callable){
            SevenCallable s = (SevenCallable)thread;
            s.setEndTime(time);
        }
    }
    //+++++++++++++++++++++++++++++重写所有的方法++++++++++++++++++++++++//

    @Override
    protected <T> SevenFutureTask<T> newTaskFor(Runnable runnable, T value) {

        return new SevenFutureTask<T>(runnable,value);
    }

    @Override
    protected <T> SevenFutureTask<T> newTaskFor(Callable<T> callable) {

       return new SevenFutureTask(callable);
    }

    @Override
    public Future<?> submit(Runnable task) {
       if (task == null) {
           throw new NullPointerException();
       }
        SevenFutureTask<Void> ftask = newTaskFor(task,null);
        execute(ftask);
        return ftask;

    }

    @Override
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) {
            throw new NullPointerException();
        }
        SevenFutureTask<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }

    @Override
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) {
            throw new NullPointerException();
        }
        SevenFutureTask<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

    @Override
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
        return super.invokeAny(tasks);
    }

    @Override
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        return super.invokeAny(tasks, timeout, unit);
    }

    @Override
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
        return super.invokeAll(tasks);
    }

    @Override
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
        return super.invokeAll(tasks, timeout, unit);
    }
}
